<?php
namespace Fiestissima\CRM\Controller;

use Fiestissima\CRM\Entity\ClienteEmpresa;
use Fiestissima\CRM\Entity\ClientePersona;
use Fiestissima\CRM\Entity\OrdenCompra;
use Fiestissima\CRM\Entity\OrdenCompraPago;
use Fiestissima\CRM\Entity\OrdenCompraProducto;
use Fiestissima\CRM\Entity\ProductoMarca;
use Fiestissima\CRM\Entity\ProductoTipo;
use Fiestissima\CRM\Entity\Precio;
use Fiestissima\CRM\Entity\Producto;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;

use \Doctrine\DBAL\DBALException;

class AjaxController extends Controller
{

    public function guardarStockAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $prId = $request->request->get('pr_id');
            $prStock = $request->request->get('prodStock');
            $prStockAlerta = $request->request->get('prodStockAlerta');

            try
            {
                $em = $this->getDoctrine()->getManager('fiestissima');
                $producto = $em->getRepository('FiestissimaCRM:Producto')->find($prId);

                if (!$producto) {
                    throw new Exception('Producto no encontrado');
                }

                $producto->setPrStock($prStock);
                $producto->setPrStockAlerta($prStockAlerta);
                $em->flush();

                return new Response("Stock actualizado!");

            }catch (Exception $e)
            {
                return new Response($e->getMessage(), 500);
            }
        }
    }

    public function getProductoStockAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $prId = $request->request->get('id');

            $producto = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:Producto', 'fiestissima')
                ->find($prId);

            $responseArray = array();
            $responseArray['producto'] = $producto->getPrNombre();
            $responseArray['productoStock'] = $producto->getPrStock();
            $responseArray['productoStockAlerta'] = $producto->getPrStockAlerta();

            return new Response(json_encode($responseArray));
        }
    }

    public function guardarNuevoTipoAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            if($request->request->get('tipoNombre')) {
                $tipoNombre = $request->request->get('tipoNombre');

                $repo = $this->getDoctrine()->getRepository('FiestissimaCRM:ProductoTipo', 'fiestissima');
                $query = $repo->createQueryBuilder('pt')
                    ->select('pt, MAX(pt.tipo_id) AS max_id');
                $maxId = $query->getQuery()->getResult();

                $newId = $maxId[0]['max_id']+1;

                $nuevoTipo = new ProductoTipo();
                $nuevoTipo->setTipoId($newId);
                $nuevoTipo->setTipoNombre($tipoNombre);

                try
                {
                    $em = $this->getDoctrine()->getManager('fiestissima');
                    $em->persist($nuevoTipo);
                    $em->flush();

                    $jsonResponse = array();
                    $jsonResponse['nuevo'] = $tipoNombre;
                    $jsonResponse['tipos'] = array();
                    $repository = $this->getDoctrine()->getRepository('FiestissimaCRM:ProductoTipo', 'fiestissima');
                    $tipos = $repository->findAll();

                    foreach($tipos as $t)
                    {
                        array_push($jsonResponse['tipos'], array('tipo'=>$t->getTipoNombre(), 'value' => $t->getTipoId()));
                    }

                    $response = new JsonResponse();
                    $response->setData($jsonResponse);

                    return $response;

                }catch (\Doctrine\DBAL\DBALException $e)
                {
                    if(strpos($e->getMessage(), "1062 Duplicate entry") !== false)
                    {
                        return new Response("El tipo {$tipoNombre} ya existe!", 500);
                    }else{
                        return new Response($e->getMessage(), 500);
                    }
                }

            }else{
                return new Response("Error!", 500);
            }
        }
    }

    public function guardarNuevaMarcaAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            //toma datos del formulario
            if($request->request->get('marcaNombre')) {
                $marcaNombre = $request->request->get('marcaNombre');

                $repo = $this->getDoctrine()->getRepository('FiestissimaCRM:ProductoMarca', 'fiestissima');
                $query = $repo->createQueryBuilder('pm')
                    ->select('pm, MAX(pm.marca_id) AS max_id');
                $maxId = $query->getQuery()->getResult();

                $newId = $maxId[0]['max_id']+1;

                $nuevaMarca = new ProductoMarca();
                $nuevaMarca->setMarcaId($newId);
                $nuevaMarca->setMarcaNombre($marcaNombre);

                try
                {
                    $em = $this->getDoctrine()->getManager('fiestissima');
                    $em->persist($nuevaMarca);
                    $em->flush();

                    $jsonResponse = array();
                    $jsonResponse['nueva'] = $marcaNombre;
                    $jsonResponse['marcas'] = array();
                    $repository = $this->getDoctrine()->getRepository('FiestissimaCRM:ProductoMarca', 'fiestissima');
                    $marcas = $repository->findAll();

                    foreach($marcas as $m)
                    {
                        array_push($jsonResponse['marcas'], array('marca'=>$m->getMarcaNombre(), 'value' => $m->getMarcaId()));
                    }

                    $response = new JsonResponse();
                    $response->setData($jsonResponse);

                    return $response;

                }catch (DBALException $e)
                {
                    if(strpos($e->getMessage(), "1062 Duplicate entry") !== false)
                    {
                        return new Response("La marca {$marcaNombre} ya existe!", 500);
                    }else{
                        return new Response($e->getMessage(), 500);
                    }
                }
            }else{
                return new Response("Error!", 500);
            }
        }
    }

    public function guardarNuevoPrecioAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            //toma datos del formulario
            $prId = $request->request->get('pr_id');

            $producto = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:Producto', 'fiestissima')
                ->find($prId);

            $precioValor = $request->request->get('precioValor');
            $fechaDesde = $this->parseDateToDatabase($request->request->get('fechaDesde'));
            if(strlen($request->request->get('fechaHasta')) != 0)
            {
                $fechaHasta = $this->parseDateToDatabase($request->request->get('fechaHasta'));
            }else{
                $fechaHasta = null;
            }


            //borrar el null de actual con el nuevo fecha desde
            $repo = $this->getDoctrine()->getRepository('FiestissimaCRM:Precio', 'fiestissima');
            $query = $repo->createQueryBuilder('p')
                ->where('p.pre_hasta IS NULL')
                ->andWhere('p.producto = :prod')
                ->setParameter('prod', $producto)
                ->getQuery();

            $precio_viejo = $query->getResult();

            if(count($precio_viejo) == 1)
            {
                $em = $this->getDoctrine()->getManager('fiestissima');
                $precio_viejo[0]->setPreHasta($fechaDesde);
                $em->persist($precio_viejo[0]);
                $em->flush();

                //guardar el precio nuevo

                $precio_nuevo = new Precio();

                $precio_nuevo->setProducto($producto);
                $precio_nuevo->setPreValor($precioValor);
                $precio_nuevo->setPreDesde($fechaDesde);
                $precio_nuevo->setPreHasta($fechaHasta);

                $query = $repo->createQueryBuilder('p')
                    ->select('p, MAX(p.pre_id) AS max_id');
                $maxId = $query->getQuery()->getResult();

                $newId = $maxId[0]['max_id']+1;

                $precio_nuevo->setPreId($newId);


                $em->persist($precio_nuevo);
                $em->flush();

                return new Response("Precio guardado OK!!!");
            }else{
                return new Response("Error de precio: ".count($precio_viejo), 500);
            }
        }
    }

    public function verPreciosProductoAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $prId = $request->request->get('id');

            $producto = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:Producto', 'fiestissima')
                ->find($prId);

            $repo = $this->getDoctrine()->getRepository('FiestissimaCRM:Precio', 'fiestissima');

            $query = $repo->createQueryBuilder('precio')
                ->where('precio.producto = :prod')
                ->setParameter('prod', $producto)
                ->orderBy('precio.pre_desde', 'DESC')
                ->getQuery();

            $precios = $query->getResult();

            $json = array();

            //ponemos en el json que sera response el producto para el titulo del modal
            $json['producto'] = $producto->getPrNombre();

            $f = 0;
            foreach($precios as $p)
            {
                if($p->getPreHasta() != null)
                {
                    $json['precio'.$f] = array('pre_id' =>$p->getPreId(),
                        'pr_id' => $p->getProducto()->getPrId(),
                        'pre_desde' => $this->parseDateToHuman($p->getPreDesde()),
                        'pre_hasta' => $this->parseDateToHuman($p->getPreHasta()),
                        'pre_valor' => $p->getPreValor());
                }else{
                    $json['precio'.$f] = array('pre_id' =>$p->getPreId(),
                        'pr_id' => $p->getProducto()->getPrId(),
                        'pre_desde' => $this->parseDateToHuman($p->getPreDesde()),
                        'pre_hasta' => "--",
                        'pre_valor' => $p->getPreValor());
                }

                $f++;
            }

            $response = new JsonResponse();
            $response->setData($json);
//            $response->setStatusCode(404);

            return $response;
//              return new Response(count($precios));
        }
    }

    public function guardarProductoYPrecioAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            //obtiene datos de post
            $prodNombre = $request->request->get('producto')['prNombre'];
            $prodDescripcion = $request->request->get('producto')['prDescripcion'];
            $tipoId = $request->request->get('producto')['type'];
            $marcaId = $request->request->get('producto')['brand'];
            $precio = $request->request->get('producto')['precio'];

            $tipo = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:ProductoTipo', 'fiestissima')
                ->find($tipoId);

            $marca = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:ProductoMarca', 'fiestissima')
                ->find($marcaId);

            $idDB = $this->getDoctrine()->getRepository('FiestissimaCRM:Producto', 'fiestissima');
            $query = $idDB->createQueryBuilder('p')
                ->select('p, MAX(p.pr_id) AS max_id');
            $maxId = $query->getQuery()->getResult();

            $newId = $maxId[0]['max_id']+1;

            $nuevoProducto = new Producto();

            $nuevoProducto->setPrNombre($prodNombre);
            $nuevoProducto->setPrDescripcion($prodDescripcion);
            $nuevoProducto->setBrand($marca);
            $nuevoProducto->setType($tipo);
            $nuevoProducto->setPrId($newId);

            $nuevoPrecio = new Precio();
            $nuevoPrecio->setProducto($nuevoProducto);
            $nuevoPrecio->setPreValor($precio);
            $nuevoPrecio->setPreDesde(date("Y-m-d"));
            $nuevoPrecio->setPreHasta(null);

            $idPrecioDB = $this->getDoctrine()->getRepository('FiestissimaCRM:Precio', 'fiestissima');
            $queryPrecioID = $idPrecioDB->createQueryBuilder('p')
                ->select('p, MAX(p.pre_id) AS max_id');
            $maxPrecioId = $queryPrecioID->getQuery()->getResult();

            $newPrecioId = $maxPrecioId[0]['max_id']+1;

            $nuevoPrecio->setPreId($newPrecioId);

            try
            {
                //guardar precio
                //guardar producto
                $em = $this->getDoctrine()->getManager('fiestissima');
                $em->persist($nuevoProducto);
                $em->persist($nuevoPrecio);
                $em->flush();

                return new Response("Producto {$nuevoProducto} guardado!");
            }catch (\Doctrine\DBAL\DBALException $e)
            {
                if(strpos($e->getMessage(), "1062 Duplicate entry") !== false)
                {
                    return new Response("El producto {$nuevoProducto->getPrNombre()} ya existe!", 500);
                }else{
                    return new Response($e->getMessage(), 500);
                }
            }

        }
    }

    public function guardarClientePersonaAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $nroDoc = $request->request->get('clientePersona')['cNroDoc'];
            $tipoDoc = $request->request->get('clientePersona')['cTipoDoc'];
            $tipoIVA = $request->request->get('clientePersona')['cTipoIva'];
            $nombre = $request->request->get('clientePersona')['cpNombre'];
            $apellido = $request->request->get('clientePersona')['cpApellido'];

            $cp = new ClientePersona();
            $cp->setCNroDoc($nroDoc);
            $cp->setCTipoIva($tipoIVA);
            $cp->setCTipoDoc($tipoDoc);
            $cp->setCpNombre($nombre);
            $cp->setCpApellido($apellido);

            $idDB = $this->getDoctrine()->getRepository('FiestissimaCRM:Cliente', 'fiestissima');
            $query = $idDB->createQueryBuilder('c')
                ->select('c, MAX(c.c_id) AS max_id');
            $maxId = $query->getQuery()->getResult();

            $newId = $maxId[0]['max_id']+1;

            $cp->setCId($newId);

            try
            {
                //Conecta a DB
                $em = $this->getDoctrine()->getManager('fiestissima');
                $em->persist($cp);
                $em->flush();

                return new Response("Cliente {$cp} guardado!");
            }catch (\Doctrine\DBAL\DBALException $e)
            {
                if(strpos($e->getMessage(), "1062 Duplicate entry") !== false)
                {
                    return new Response("El cliente {$cp->getCTipoDoc()} - {$cp->getCNroDoc()} ya existe!", 500);
                }else{
                    return new Response($e->getMessage(), 500);
                }
            }


        }
    }

    public function guardarClienteEmpresaAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $nroDoc = $request->request->get('clienteEmpresa')['cNroDoc'];
            $tipoDoc = $request->request->get('clienteEmpresa')['cTipoDoc'];
            $tipoIVA = $request->request->get('clienteEmpresa')['cTipoIva'];
            $contacto = $request->request->get('clienteEmpresa')['ceContacto'];
            $razon_social = $request->request->get('clienteEmpresa')['ceRazonSocial'];

            $ce = new ClienteEmpresa();
            $ce->setCNroDoc($nroDoc);
            $ce->setCTipoDoc($tipoDoc);
            $ce->setCTipoIva($tipoIVA);
            $ce->setCeContacto($contacto);
            $ce->setCeRazonSocial($razon_social);

            $idDB = $this->getDoctrine()->getRepository('FiestissimaCRM:Cliente', 'fiestissima');
            $query = $idDB->createQueryBuilder('c')
                ->select('c, MAX(c.c_id) AS max_id');
            $maxId = $query->getQuery()->getResult();

            $newId = $maxId[0]['max_id']+1;

            $ce->setCId($newId);

            //Conecta a DB
            $em = $this->getDoctrine()->getManager('fiestissima');
            $em->persist($ce);
            $em->flush();

            return new Response("Empresa {$ce} guardada!");
        }
    }

    public function guardarOrdenCompraAction(Request $request)
	{
		if($request->isXmlHttpRequest()) {

            //Conecta a DB
            $em = $this->getDoctrine()->getManager('fiestissima');

            $totalContado = 0;
            $totalTarjeta = 0;
			//Toma de session el array de DiarioProducto y el ID del Diario actual
			$session = $request->getSession(); 
            $oc = $session->get('ordenCompra');

            //toma cliente si viene el ID
            if(count($request->request) > 0)
            {
                $clienteId = $request->request->get('clienteId');
                $clienteRepo = $this->getDoctrine()->getRepository('FiestissimaCRM:Cliente', 'fiestissima');
                $cliente = $clienteRepo->find($clienteId);
                $oc->setCliente($cliente);
            }

            //ordencompra
            $idOc = $this->getDoctrine()->getRepository('FiestissimaCRM:OrdenCompra', 'fiestissima');
            $query = $idOc->createQueryBuilder('oc')
                ->select('oc, MAX(oc.orden_compra_id) AS max_id');
            $maxOcId = $query->getQuery()->getResult();

            $maxOrCoId = $maxOcId[0]['max_id'];
            $oc->setOrdenCompraId($maxOrCoId+1);
            $oc->setOrdenCompraFecha(date("Y-m-d"));
            $oc->setOrdenCompraDescuento(0);

            //ordencomprapagos
            if(count($oc->getOrdenCompraPago()) > 0)
            {
                $oppgIdSetter = 0;

                $idPg = $this->getDoctrine()->getRepository('FiestissimaCRM:OrdenCompraPago', 'fiestissima');
                $query = $idPg->createQueryBuilder('oppg')
                    ->select('oppg, MAX(oppg.orden_compra_pago_id) AS max_id');
                $maxPgId = $query->getQuery()->getResult();

                $maxOppgId = $maxPgId[0]['max_id'];

                foreach($oc->getOrdenCompraPago() as $p)
                {
                    $oppgIdSetter +=1;
                    $p->setOrdenCompraPagoId($maxOppgId+$oppgIdSetter);
                    $p->setOrdenCompra($oc);

                    $fp = $em->getRepository('FiestissimaCRM:FormaPago', 'fiestissima')->find($p->getFormaPago()->getFormaPagoId());
                    $p->setFormaPago($fp);

                    if($p->getFormaPago() == "Efectivo" || $p->getFormaPago() == "Débito")
                    {
                        $totalContado += $p->getOrdenCompraPagoSubtotal();
                    }else{
                        $totalTarjeta += $p->getOrdenCompraPagoSubtotal();
                    }

                    $p->setOrdenCompra($oc);
                }
            }

            //ordencompraproductos
            $opprIdSetter = 0;

            $idPr = $this->getDoctrine()->getRepository('FiestissimaCRM:OrdenCompraProducto', 'fiestissima');
            $query = $idPr->createQueryBuilder('oppr')
                ->select('oppr, MAX(oppr.orden_compra_producto_id) AS max_id');
            $maxPrId = $query->getQuery()->getResult();

            $maxOpprId = $maxPrId[0]['max_id'];

            foreach($oc->getOrdenCompraProducto() as $pr)
            {
                $opprIdSetter += 1;
                $pr->setOrdenCompraProductoId($maxOpprId + $opprIdSetter);
                $pr->setOrdenCompra($oc);

                $p = $em->getRepository('FiestissimaCRM:Producto', 'fiestissima')->find($pr->getProducto()->getPrId());
                $pr->setProducto($p);

                $pr->setOrdenCompra($oc);

                //actualizar stock
                $p->setPrStock($p->getPrStock()-$pr->getOrdenCompraProductoCantidad());

            }

            //ACTUALIZA VALORES DE OC
            $oc->setOrdenCompraContado($totalContado);
            $oc->setOrdenCompraTarjeta($totalTarjeta);
            $oc->setOrdenCompraTotal($totalContado+$totalTarjeta);

            try{
                //Persiste en DB la orden de compra
                $em->persist($oc);
                $em->flush();
            }catch (\Exception $e){
                $this->get('logger')->error("CATCHED ERROR -> ".$oc->getOrdenCompraProducto()[0]->getOrdenCompraId());
                $this->get('logger')->error($e->getMessage());
                $this->get('logger')->error($e->getTraceAsString());
            }
 			
			return new Response("Orden de Compra número {$oc->getOrdenCompraId()} guardada!");
		}
	}
	
	public function agregarDiarioProductoSesionAction(Request $request)
	{
		if($request->isXmlHttpRequest()) {

            $cant = $request->request->get('ordenCompraProducto')['orden_compra_producto_cantidad'];
            $prId = $request->request->get('ordenCompraProducto')['producto'];
            $subt = $request->request->get('productoSubtotal');

            $producto = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:Producto', 'fiestissima')
                ->find($prId);

            //crea nuevo objeto OrdenCompraProducto y guarda en OrdenCompra de session

            $ocpr = new OrdenCompraProducto();
            $ocpr->setOrdenCompraProductoCantidad($cant);
            $ocpr->setProducto($producto);

            $session = $request->getSession();
            $oc = $session->get('ordenCompra');
            $oc->addOrdenCompraProducto($ocpr);

            $session->set('ordenCompra', $oc);

			return new Response("<tr><td>{$producto}</td><td>{$cant}</td><td id=\"subt-prod\">{$subt}</td></tr>");
		}
		
	}

    public function agregarFormaPagoSessionAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $fpID = $request->request->get('ordenCompraPago')['formaPago'];
            $subt = $request->request->get('ordenCompraPago')['orden_compra_pago_subtotal'];

            $fp = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:FormaPago', 'fiestissima')
                ->find($fpID);

            $ocp = new OrdenCompraPago();

            $this->get('logger')->info(' **** Subtotal: '.$subt);
            $this->get('logger')->info(' **** Recargo: '.$fp->getFormaPagoRecargo());

            $ocp->setOrdenCompraPagoSubtotal($subt * $fp->getFormaPagoRecargo());
            $ocp->setFormaPago($fp);

            $session = $request->getSession();
            $oc = $session->get('ordenCompra');
            $oc->addOrdenCompraPago($ocp);

            $session->set('ordenCompra', $oc);

            return new Response($ocp->getOrdenCompraPagoSubtotal());
//            return new Response("Orden Compra Temporal Productos: ".count($oc->getOrdenCompraProducto())."    || Orden Compra Temporal Pagos: ".count($oc->getOrdenCompraPago()));
        }
    }

	public function actualizarDiarioProductoPrecioAction(Request $request)
	{
		if($request->isXmlHttpRequest()) {

            $cant = $request->request->get('ordenCompraProducto')['orden_compra_producto_cantidad'];
            $prId = $request->request->get('ordenCompraProducto')['producto'];

            $producto = $this->getDoctrine()
                ->getRepository('FiestissimaCRM:Producto', 'fiestissima')
                ->find($prId);

			//obtiene precio de lista del producto seleccionado
			$precioRepo = $this->getDoctrine()->getRepository('FiestissimaCRM:Precio', 'fiestissima');
			$pl = $precioRepo->findOneBy(array('producto' => $producto, 'pre_hasta' => null));
			
			//calculo precio subtotal
			$subtotal = $cant * $pl->getPreValor();

			return new Response(round($subtotal,2));
		}
		
	}

    public function actualizarDiarioProductoAction(Reuqest $request)
    {
        if($request->isXmlHttpRequest())
        {
            $repo = $this->getDoctrine()->getRepository('FiestissimaCRM:Diario', 'fiestissima');

            $query = $repo->createQueryBuilder('d')
                ->where('d.d_fecha = CURRENT_DATE()')
                ->getQuery();

            $diario = $query->getResult();
            $diarioproductos = $diario[0]->getDiarioproducto();

            //todo parsear $diarioproductos, ver partidos cai
            $responseString ="";

            return new Response($responseString);
        }
    }

    public function removeSessionOrdenCompraAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
           //borra orden de compra temporal de session
            $session = $request->getSession();
            $session->remove('ordenCompra');

            return new Response("Orden de Compra temporal borrada");
        }
    }

    public function createSessionOrdenCompraAction(Request $request)
    {
        if($request->isXmlHttpRequest())
        {
            $oc = new OrdenCompra();

            $session = $request->getSession();
            $session->set('ordenCompra', $oc);

            return new Response("Orden de compra temporal creada");
        }
    }

    /**
     * Este método toma una fecha en YYYY-MM-DD y la devuelve en DD/MM/YYYY
     * @param $f
     * @return string
     */
    private function parseDateToHuman($f)
    {
        $year = substr($f, 0, 4);
        $day = substr($f, -2);
        $month = substr($f, 5, 2);

        return $day."/".$month."/".$year;
    }

    /**
     * Este método toma una fecha en DD/MM/YYYY y la devuelve en YYYY-MM-DD
     * @param $f
     * @return string
     */
    private function parseDateToDatabase($f)
    {
        $year = substr($f, -4);
        $day = substr($f, 0, 2);
        $month = substr($f, 3, 2);

        return $year."-".$month."-".$day;
    }
}